<template>
    <div>
        <!-- 消息容器 -->
        <div class="message-content" ref="msgContent" :style="`padding-bottom: ${emojiShow ? 6.6667 : 2.4}rem;`">
            <van-pull-refresh v-model="isLoading" @refresh="onRefresh" pulling-text="下拉加载更多" loosing-text="下拉加载更多" :disabled="isDisabled">
                <ul class="message-list-content">
                    <li v-for="(item,index) in dataList" :key="index">
                        <!-- 自己消息框 -->
                        <div class="me msg-box-right" v-if="item.userId._id === userId">
                            <!-- 消息容器（群中人名、发送时间） -->
                            <div class="msg-content right">
                                <div class="nick" v-if="$route.params.type==='groupChat'">{{ item.userId.nick }}</div>
                                <div class="msg-del">
                                    <!-- 时间 -->
                                    <div class="msg-time">{{ item.time }}</div>
                                    <!-- 文字 -->
                                    <div class="bubble bubble-right" v-if="item.msgType == 0">{{ item.message }}</div>
                                    <!-- 图片 -->
                                    <div class="bubble bubble-right" v-else>
                                        <div class="msg-pic" @click="lookPic($baseUrl + item.message)">
                                            <van-image
                                                height="3rem"
                                                lazy-load
                                                fit="cover"
                                                :src="$baseUrl + item.message"
                                            />
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="user-pic" @click="goUserHome(item.userId._id)">
                                <img :src="$baseUrl + item.userId.imgUrl" alt="">
                            </div>
                        </div>
                        <!-- 对方消息框 -->
                        <div class="other msg-box-left" v-else>
                            <div class="user-pic" @click="goUserHome(item.userId._id)">
                                <img :src="$baseUrl + item.userId.imgUrl" alt="">
                            </div>
                            <div class="msg-content left">
                                <div class="nick" v-if="$route.params.type==='groupChat'">{{ item.userId.nick }}</div>
                                <div class="msg-del">
                                    <!-- 文字 -->
                                    <div class="bubble bubble-left" v-if="item.msgType == 0">{{ item.message }}</div>
                                    <!-- 图片 -->
                                    <div class="bubble bubble-left" v-else>
                                        <div class="msg-pic" @click="lookPic($baseUrl + item.message)">
                                            <van-image
                                                height="3rem"
                                                lazy-load
                                                fit="cover"
                                                :src="$baseUrl + item.message"
                                            />
                                        </div>
                                    </div>
                                    <!-- 时间 -->
                                    <div class="msg-time">{{ item.time }}</div>
                                </div>
                            </div>
                        </div>
                    </li>
                </ul>
            </van-pull-refresh>
        </div>
        <!-- 底部输入框 -->
        <div class="bottom">
            <div class="bottom-ipt">
                <input type="text" v-model="value">
                <!-- 发送按钮 -->
                <div class="send-btn" @click.enter="sendMsgBtn">
                    <img src="@/assets/fasong.png" alt="">
                </div>
            </div>
            <div class="bottom-other" ref="bottomOther">
                <img @click="handleEmojiShow" class="emoji" src="@/assets/emoji.png" alt="">
                <van-uploader
                    multiple
                    :max-count="9"
                    accept="image/png, image/jpeg, image/jpg"
                    :after-read="afterRead"
                    @click-upload="emojiShow = false"
                >
                    <img src="@/assets/tupian.png" alt="">
                </van-uploader>
            </div>
            <!-- emoji表情 -->
            <div class="other-content" v-show="emojiShow">
                <EmojiList @emoji="emojiChoose"/>
            </div>
        </div>
    </div>
</template>

<script>
import EmojiList from '@/components/EmojiList'
import { Toast, ImagePreview } from 'vant'
import { mapState } from 'vuex'
import { reqPrivateUploadPhoto, reqPrivateUploadPhotos, reqGroupUploadPhoto, reqGroupUploadPhotos } from '@/api'
import { formatDate } from '@/utils'
export default {
    components: {
        EmojiList
    },
    props: ['dataList', 'isDisabled'],
    data() {
        return {
            value: '',
            messageList: this.$store.state.socket.messageList,  // vuex消息列表
            emojiShow: false,  // emoji弹出框
            fileList: [],  // 发送图片
            isLoading: false,  // 下拉刷新loading
            isPullRefresh: false,  // 是否是下拉刷新
            msgContentHeightArr: [],  // 存放聊天记录高度的数组
            chatType: this.$route.params.type  // 聊天类型（私聊、群聊）
        }
    },
    computed: {
        ...mapState({
            userId: state => state.login.userInfo._id,
            nick: state => state.login.userInfo.nick,
            imgUrl: state => state.login.userInfo.imgUrl,
            position: state => state.socket.position
        })
    },
    methods: {
        // 初始化滚动高度
        _initScrollTop() {
            this.$refs.msgContent.scrollTop = this.$refs.msgContent.scrollHeight
        },
        // 去用户主页
        goUserHome(_id) {
            this.$router.push({
                path: '/userhome',
                query: {
                    _id
                }
            })
        },
        // emoji表情事件回调
        handleEmojiShow() {
            this.emojiShow = !this.emojiShow
        },
        // 选择的emoji
        emojiChoose(e) {
            this.value = this.value + e
        },
        // 键盘enter按下事件
        handleKeyCode(e) {
            // enter键（keycode为13）
            if(e.keyCode === 13) {
                this.sendMsgBtn()
            }
        },
        // 发送消息事件回调
        sendMsgBtn() {
            if (!this.value) {
                Toast('消息内容不能为空')
                return
            }
            let dataMsg = {
                userId: {
                    _id: this.userId,
                    nick: this.nick,
                    imgUrl: this.imgUrl
                },
                msgType: 0,
                message: this.value,
                time: formatDate(new Date())  // 这里的时间只是用来push到自己的消息中的，对方接收的时间是后端提供的
            }
            this.dataList.push(dataMsg)
            if (this.chatType === 'friendChat') {
                // 一对一聊天
                this.sendPrivateChat(dataMsg)
            } else {
                // 群聊
                this.sendGroupChat(dataMsg)
            }
            this.value = ''
        },
        // 发送一对一消息
        sendPrivateChat(dataMsg) {
            this.$socket.emit('private_chat', dataMsg, this.userId, this.$route.query._id)
        },
        // 发送群聊消息
        sendGroupChat(dataMsg) {
            this.$socket.emit('group_chat', dataMsg, this.userId, this.$route.query._id)
        },
        // 图片上传 reqGroupUploadPhoto
        async afterRead(file) {
            if (this.chatType === 'friendChat') {
                // 一对一聊天
                if (!file.length) {
                    // 单图片上传
                    let formData = new FormData()
                    formData.append('photo', file.file)
                    let res = await reqPrivateUploadPhoto(formData)
                    if (res.res_code === 200) {
                        let dataMsg = {
                            userId: {
                                _id: this.userId,
                                nick: this.nick,
                                imgUrl: this.imgUrl
                            },
                            msgType: 1,
                            message: res.url,
                            time: formatDate(new Date())
                        }
                        this.dataList.push(dataMsg)
                        this.sendPrivateChat(dataMsg)
                    } else {
                        Toast.fail('发送失败')
                    }
                } else {
                    // 多图片上传
                    let formData = new FormData()
                    //需要依次添加进去
                    for (let i = 0; i < file.length; i++) {
                        formData.append('photos', file[i].file)
                    }
                    let res = await reqPrivateUploadPhotos(formData)
                    if (res.res_code === 200) {
                        res.url.forEach(i => {
                            let myData = {
                                userId: {
                                    _id: this.userId,
                                    nick: this.nick,
                                    imgUrl: this.imgUrl
                                },
                                msgType: 1,
                                message: i,
                                time: formatDate(new Date())
                            }
                            this.dataList.push(myData)
                        })
                        let dataMsg = {
                                userId: {
                                    _id: this.userId,
                                    nick: this.nick,
                                    imgUrl: this.imgUrl
                                },
                                msgType: 1,
                                message: res.url,
                                time: formatDate(new Date())
                        }
                        this.sendPrivateChat(dataMsg)
                    } else {
                        Toast.fail('发送失败')
                    }
                }
            } else {
                // 群聊
                if (!file.length) {
                    // 单图片上传
                    let formData = new FormData()
                    formData.append('photo', file.file)
                    let res = await reqGroupUploadPhoto(formData)
                    if (res.res_code === 200) {
                        let dataMsg = {
                            userId: {
                                _id: this.userId,
                                nick: this.nick,
                                imgUrl: this.imgUrl
                            },
                            msgType: 1,
                            message: res.url,
                            time: formatDate(new Date())
                        }
                        this.dataList.push(dataMsg)
                        this.sendGroupChat(dataMsg)
                    } else {
                        Toast.fail('发送失败')
                    }
                } else {
                    // 多图片上传
                    let formData = new FormData()
                    //需要依次添加进去
                    for (let i = 0; i < file.length; i++) {
                        formData.append('photos', file[i].file)
                    }
                    let res = await reqGroupUploadPhotos(formData)
                    if (res.res_code === 200) {
                        res.url.forEach(i => {
                            let myData = {
                                userId: {
                                    _id: this.userId,
                                    nick: this.nick,
                                    imgUrl: this.imgUrl
                                },
                                msgType: 1,
                                message: i,
                                time: formatDate(new Date())
                            }
                            this.dataList.push(myData)
                        })
                        let dataMsg = {
                                userId: {
                                    _id: this.userId,
                                    nick: this.nick,
                                    imgUrl: this.imgUrl
                                },
                                msgType: 1,
                                message: res.url,
                                time: formatDate(new Date())
                        }
                        this.sendGroupChat(dataMsg)
                    } else {
                        Toast.fail('发送失败')
                    }
                }
            }
            
        },
        // 查看图片
        lookPic(imgUrl) {
            ImagePreview({
                images: [imgUrl],
                loop: false,
                closeable: true
            })
        },
        // 下拉刷新
        onRefresh() {
            this.isPullRefresh = true
            this.$parent.pageNum += 1
            if (this.chatType === 'friendChat') {
                // 一对一聊天
                this.$parent.getFriendInfo(this.$parent.pageNum)
            } else {
                // 群聊
                this.$parent.getGroupInfo(this.$parent.pageNum)
            }
            setTimeout(() => {
                this.isLoading = false
            }, 1000)
        }
    },
    created() {
        window.addEventListener('keydown', this.handleKeyCode, true)
    },
    mounted() {
        this._initScrollTop()
    },
    beforeDestroy() {
        window.removeEventListener('keydown', this.handleKeyCode, true)
    },
    watch: {
        messageList(value) {
            let needValue = value.slice(-this.position)
            for (let i = 0; i < needValue.length; i++) {
                this.dataList.push(needValue[i])
            }
        },
        dataList() {
            this.$nextTick(() => {
                this.msgContentHeightArr.unshift(this.$refs.msgContent.scrollHeight)
                if (this.isPullRefresh) {
                    // 下拉刷新
                    this.$refs.msgContent.scrollTop = this.msgContentHeightArr[0] - this.msgContentHeightArr[1]
                    this.isPullRefresh = false
                } else {
                    // 首次加载数据、发送消息
                    this.$refs.msgContent.scrollTop = this.$refs.msgContent.scrollHeight
                }
            })
        }
    },
}
</script>

<style lang="less" scoped>
.message-content::-webkit-scrollbar {
    display: none;
}
.message-content {
    width: 100%;
    height: 100vh;
    padding: 1.3333rem 0 0;
    box-sizing: border-box;
    background-color: #f1f1f1;
    overflow: auto;
    scrollbar-width: none;
    -ms-overflow-style: none; 
    .message-list-content {
        padding: .4rem .3333rem;
        box-sizing: border-box;
        .me, .other {
            width: 100%;
            min-height: 1.2667rem;
            margin-bottom: .5333rem;
            display: flex;
            .user-pic {
                width: 1.2667rem;
                height: 1.2667rem;
                border-radius: 50%;
                overflow: hidden;
                img {
                    width: 100%;
                    height: 100%;
                }
            }
            .msg-content {
                display: flex;
                flex-direction: column;
                .msg-del {
                    display: flex;
                }
                .bubble {
                    max-width: 6rem;
                    min-height: 1.2667rem;
                    margin: 0 .2rem;
                    line-height: .6667rem;
                    white-space: pre-wrap;
                    word-break: break-all;
                    word-wrap: break-word;
                    border-radius: .1333rem;
                    padding: .3333rem .2rem;
                    box-sizing: border-box;
                    font-size: .4rem;
                    display: flex;
                    align-items: center;
                    margin: .1333rem 0;
                    .msg-pic {
                        img {
                            width: 100%;
                        }
                    }
                }
                .bubble-left {
                    // background-color: #fff;  // 纯色
                    background-image: linear-gradient(to right, #cdd6f2, #e2e2e5);  // 渐变色
                    margin-left: .2667rem;
                }
                .bubble-right {
                    // background-color: #b6e2f9;  // 纯色
                    background-image: linear-gradient(to left, #498adf, #61cffb);  // 渐变色
                    margin-right: .2667rem;
                }
            }
            .msg-time {
                align-self: flex-end;
                padding: .2rem .1333rem;
            }
            .right {
                align-items: flex-end;
                .nick {
                    margin-right: 0.2667rem;
                }
            }
            .left {
                align-items: flex-start;
                .nick {
                    margin-left: 0.2667rem;
                }
            }
        }
        .msg-box-right {
            justify-content: flex-end;
        }
    }
}
.bottom {
    width: 100%;
    background-color: #f8f8f8;
    border-top: 0.04rem solid #dbdada;
    position: fixed;
    padding: .2rem .2667rem;
    box-sizing: border-box;
    left: 0;
    bottom: 0;
    .bottom-ipt {
        display: flex;
    }
    input {
        width: 100%;
        height: .9333rem;
        border: none;
        padding: 0 .2rem;
        font-size: .4rem;
        border-radius: .1333rem;
    }
    .send-btn {
        width: 1.6rem;
        height: .9333rem;
        background-color: #b6e2f9;
        margin-left: .2667rem;
        border-radius: .1333rem;
        display: flex;
        justify-content: center;
        align-items: center;
        img {
            width: .8rem;
            height: .8rem;
        }
    }
    .bottom-other {
        margin-top: .2667rem;
        width: 100%;
        height: .8rem;
        display: flex;
        align-items: center;
        img {
            width: .8rem;
            height: .8rem;
        }
        .emoji {
            width: .8rem;
            height: .8rem;
            margin-right: .1333rem;
        }
    }
    .other-content {
        width: 100%;
        height: 4rem;
        margin-top: .2667rem;
        overflow: auto;
        border-top: .0133rem solid #dddddd;
    }
}
</style>